﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static LightCAD.Three.Constants;
using LightCAD.Three.OpenGL;

namespace LightCAD.Three
{

    public class WebGLUtils
    {
        private WebGLExtensions extensions;
        private WebGLCapabilities capabilities;
        public WebGLUtils(WebGLExtensions _extensions = null, WebGLCapabilities _capabilities = null)
        {
            if (_extensions == null)
            {
                _extensions = new WebGLExtensions();
            }

            extensions = _extensions;

            if (_capabilities == null)
            {
                _capabilities = new WebGLCapabilities(extensions, new RenderParams());
            }
            capabilities = _capabilities;

        }
        public int convert(int p, int? encoding = null)
        {
            bool isWebGL2 = capabilities.isWebGL2;

            if (p == UnsignedByteType) return gl.UNSIGNED_BYTE;
            if (p == UnsignedShort4444Type) return gl.UNSIGNED_SHORT_4_4_4_4;
            if (p == UnsignedShort5551Type) return gl.UNSIGNED_SHORT_5_5_5_1;

            if (p == ByteType) return gl.BYTE;
            if (p == ShortType) return gl.SHORT;
            if (p == UnsignedShortType) return gl.UNSIGNED_SHORT;
            if (p == IntType) return gl.INT;
            if (p == UnsignedIntType) return gl.UNSIGNED_INT;
            if (p == FloatType) return gl.FLOAT;

            if (p == HalfFloatType)
            {
                if (isWebGL2) return gl.HALF_FLOAT;

                //gl = extensions.get("OES_texture_half_float");

                //if (gl !== null)
                //{

                //    return gl.HALF_FLOAT_OES;

                //}
                //else
                //{

                //    return 0;

                //}
            }

            if (p == AlphaFormat) return gl.ALPHA;
            if (p == RGBAFormat) return gl.RGBA;
            if (p == BGRFormat) return gl.BGR;
            if (p == BGRAFormat) return gl.BGRA;
            if (p == LuminanceFormat) return gl.LUMINANCE;
            if (p == LuminanceAlphaFormat) return gl.LUMINANCE_ALPHA;
            if (p == DepthFormat) return gl.DEPTH_COMPONENT;
            if (p == DepthStencilFormat) return gl.DEPTH_STENCIL;


            // WebGL 1 sRGB fallback

            //if (p == _SRGBAFormat)
            //{

            //	gl = extensions.get('EXT_sRGB');

            //	if (gl !== null)
            //	{

            //		return gl.SRGB_ALPHA_EXT;

            //	}
            //	else
            //	{

            //		return null;

            //	}

            //}

            // WebGL2 formats.

            if (p == RedFormat) return gl.RED;
            if (p == RedIntegerFormat) return gl.RED_INTEGER;
            if (p == RGFormat) return gl.RG;
            if (p == RGIntegerFormat) return gl.RG_INTEGER;
            if (p == RGBAIntegerFormat) return gl.RGBA_INTEGER;

            // S3TC

            if (p == RGB_S3TC_DXT1_Format || p == RGBA_S3TC_DXT1_Format || p == RGBA_S3TC_DXT3_Format || p == RGBA_S3TC_DXT5_Format)
            {
                if (encoding == sRGBEncoding)
                {
                    if (p == RGB_S3TC_DXT1_Format) return gl.COMPRESSED_SRGB_S3TC_DXT1_EXT;
                    if (p == RGBA_S3TC_DXT1_Format) return gl.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
                    if (p == RGBA_S3TC_DXT3_Format) return gl.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
                    if (p == RGBA_S3TC_DXT5_Format) return gl.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
                }
                else
                {
                    if (p == RGB_S3TC_DXT1_Format) return gl.COMPRESSED_RGB_S3TC_DXT1_EXT;
                    if (p == RGBA_S3TC_DXT1_Format) return gl.COMPRESSED_RGBA_S3TC_DXT1_EXT;
                    if (p == RGBA_S3TC_DXT3_Format) return gl.COMPRESSED_RGBA_S3TC_DXT3_EXT;
                    if (p == RGBA_S3TC_DXT5_Format) return gl.COMPRESSED_RGBA_S3TC_DXT5_EXT;
                }
            }

            // PVRTC

            if (p == RGB_PVRTC_4BPPV1_Format || p == RGB_PVRTC_2BPPV1_Format || p == RGBA_PVRTC_4BPPV1_Format || p == RGBA_PVRTC_2BPPV1_Format)
            {

                //    if (p == RGB_PVRTC_4BPPV1_Format) return gl.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
                //    if (p == RGB_PVRTC_2BPPV1_Format) return gl.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
                //    if (p == RGBA_PVRTC_4BPPV1_Format) return gl.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
                //    if (p == RGBA_PVRTC_2BPPV1_Format) return gl.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
            }

            // ETC1

            //if (p == RGB_ETC1_Format)
            //{
            //    return gl.COMPRESSED_RGB_ETC;
            //}
            // ETC2

            if (p == RGB_ETC2_Format || p == RGBA_ETC2_EAC_Format)
            {
                if (p == RGB_ETC2_Format) return (encoding == sRGBEncoding) ? gl.COMPRESSED_SRGB8_ETC2 : gl.COMPRESSED_RGB8_ETC2;
                if (p == RGBA_ETC2_EAC_Format) return (encoding == sRGBEncoding) ? gl.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : gl.COMPRESSED_RGBA8_ETC2_EAC;
            }

            // ASTC

            if (p == RGBA_ASTC_4x4_Format || p == RGBA_ASTC_5x4_Format || p == RGBA_ASTC_5x5_Format ||
                p == RGBA_ASTC_6x5_Format || p == RGBA_ASTC_6x6_Format || p == RGBA_ASTC_8x5_Format ||
                p == RGBA_ASTC_8x6_Format || p == RGBA_ASTC_8x8_Format || p == RGBA_ASTC_10x5_Format ||
                p == RGBA_ASTC_10x6_Format || p == RGBA_ASTC_10x8_Format || p == RGBA_ASTC_10x10_Format ||
                p == RGBA_ASTC_12x10_Format || p == RGBA_ASTC_12x12_Format)
            {

                if (p == RGBA_ASTC_4x4_Format) return (encoding == sRGBEncoding) ? gl.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR : gl.COMPRESSED_RGBA_ASTC_4x4_KHR;
                if (p == RGBA_ASTC_5x4_Format) return (encoding == sRGBEncoding) ? gl.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR : gl.COMPRESSED_RGBA_ASTC_5x4_KHR;
                if (p == RGBA_ASTC_5x5_Format) return (encoding == sRGBEncoding) ? gl.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : gl.COMPRESSED_RGBA_ASTC_5x5_KHR;
                if (p == RGBA_ASTC_6x5_Format) return (encoding == sRGBEncoding) ? gl.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : gl.COMPRESSED_RGBA_ASTC_6x5_KHR;
                if (p == RGBA_ASTC_6x6_Format) return (encoding == sRGBEncoding) ? gl.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : gl.COMPRESSED_RGBA_ASTC_6x6_KHR;
                if (p == RGBA_ASTC_8x5_Format) return (encoding == sRGBEncoding) ? gl.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : gl.COMPRESSED_RGBA_ASTC_8x5_KHR;
                if (p == RGBA_ASTC_8x6_Format) return (encoding == sRGBEncoding) ? gl.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : gl.COMPRESSED_RGBA_ASTC_8x6_KHR;
                if (p == RGBA_ASTC_8x8_Format) return (encoding == sRGBEncoding) ? gl.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : gl.COMPRESSED_RGBA_ASTC_8x8_KHR;
                if (p == RGBA_ASTC_10x5_Format) return (encoding == sRGBEncoding) ? gl.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : gl.COMPRESSED_RGBA_ASTC_10x5_KHR;
                if (p == RGBA_ASTC_10x6_Format) return (encoding == sRGBEncoding) ? gl.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : gl.COMPRESSED_RGBA_ASTC_10x6_KHR;
                if (p == RGBA_ASTC_10x8_Format) return (encoding == sRGBEncoding) ? gl.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : gl.COMPRESSED_RGBA_ASTC_10x8_KHR;
                if (p == RGBA_ASTC_10x10_Format) return (encoding == sRGBEncoding) ? gl.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : gl.COMPRESSED_RGBA_ASTC_10x10_KHR;
                if (p == RGBA_ASTC_12x10_Format) return (encoding == sRGBEncoding) ? gl.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : gl.COMPRESSED_RGBA_ASTC_12x10_KHR;
                if (p == RGBA_ASTC_12x12_Format) return (encoding == sRGBEncoding) ? gl.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : gl.COMPRESSED_RGBA_ASTC_12x12_KHR;
            }

            // BPTC

            if (p == RGBA_BPTC_Format)
            {
                if (p == RGBA_BPTC_Format)
                    return (encoding == sRGBEncoding) ? gl.COMPRESSED_SRGB_ALPHA_BPTC_UNORM : gl.COMPRESSED_RGBA_BPTC_UNORM;
            }
            // RGTC

            if (p == RED_RGTC1_Format || p == SIGNED_RED_RGTC1_Format || p == RED_GREEN_RGTC2_Format || p == SIGNED_RED_GREEN_RGTC2_Format)
            {

                //extension = extensions.get('EXT_texture_compression_rgtc');
                if (p == RGBA_BPTC_Format) return gl.COMPRESSED_RED_RGTC1_EXT;
                if (p == SIGNED_RED_RGTC1_Format) return gl.COMPRESSED_SIGNED_RED_RGTC1_EXT;
                //if (p == RED_GREEN_RGTC2_Format) return gl.COMPRESSED_RED_GREEN_RGTC2_EXT;
                //if (p == SIGNED_RED_GREEN_RGTC2_Format) return gl.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT;
            }
            //

            if (p == UnsignedInt248Type)
            {

                if (isWebGL2) return gl.UNSIGNED_INT_24_8;

                //gl = extensions.get('WEBGL_depth_texture');

                //if (gl !== null)
                //{

                //    return gl.UNSIGNED_INT_24_8_WEBGL;

                //}
                //else
                //{

                //    return null;

                //}

            }

            // if "p" can't be resolved, assume the user defines a WebGL constant as a string (fallback/workaround for packed RGB formats)

            //return (gl[p] != null) ? gl[p] : null;
            return 0;

        }
    }
}
